package com.baosight.risk.web.system;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.alibaba.fastjson.JSONObject;
import com.baosight.iplat4j.core.ioc.spring.PlatApplicationContext;
import com.baosight.risk.common.utils.*;
import com.baosight.risk.web.xtzy.XtzyCompanyController;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.web.util.RedirectView;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.baosight.iplat4j.core.log.Logger;
import com.baosight.iplat4j.core.log.LoggerFactory;
import com.baosight.risk.api.xtzy.IXtzyCompanyService;
import com.baosight.risk.api.xtzy.IXtzyRoleUserService;
import com.baosight.risk.api.xtzy.IXtzyUserService;
import com.baosight.risk.base.controller.BaseController;
import com.baosight.risk.common.annotation.Log;
import com.baosight.risk.common.enums.IntegralType;
import com.baosight.risk.common.result.AjaxResult;
import com.baosight.risk.service.system.entity.SysRole;
import com.baosight.risk.service.xtzy.entity.XtzyCompany;
import com.baosight.risk.service.xtzy.entity.XtzyUser;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author duanyongqiang
 * <p>
 * 系统登陆注入shrio权限管理
 */
@RestController
@RequestMapping("system")
@Slf4j
public class SysLoginController extends BaseController {
    @Autowired
    private IXtzyCompanyService companyService;
    @Autowired
    private IXtzyRoleUserService roleUserService;
    @Autowired
    private IXtzyUserService userService;
//测试机
 /*   private final static String LOGIN_URL = "https://atest.baowugroup.cn/szbw-cas/buapxPasswordValidate";

    private final static String VUE_URL = "http://localhost:8083/#/home";
    private final static String AUTH_URL = "http://atest.baowugroup.cn/szbw-umau/oauth/authorize?response_type=code&client_id=jvW2LW8CeVPposQQGh&client_secret=299E108F0832495E84D3B10A9521B79C&redirect_uri=http://localhost:8090/risk/system/riskLogin&scope=read";
    private final static String CLIENT_ID = "jvW2LW8CeVPposQQGh";
    private final static String CLIENT_SECRET = "299E108F0832495E84D3B10A9521B79C";
    private final static String REDIECT_URI = "http://localhost:8090/risk/system/riskLogin";
    private final static String OAUTH_URL = "http://atest.baowugroup.cn/szbw-umau/oauth/token";
    private final static String LOGIN2_URL = "http://localhost:8090/risk/xtzy/company/getCompany";
    private final static String USER_URL = "http://atest.baowugroup.cn/szbw-umau/user";*/

    //生产
    //private final static String LOGIN_URL = "http://a.baowugroup.cn/szbw-cas/buapxPasswordValidate";
    private final static String LOGIN_URL = ReadProperties.getValueString("LOGIN_URL");
    //private final static String VUE_URL = "http://10.70.16.197:9080/#/home";
    private final static String VUE_URL = ReadProperties.getValueString("VUE_URL");
    //private final static String AUTH_URL = "http://a.baowugroup.cn/szbw-umau/oauth/authorize?response_type=code&client_id=jvOXrzOP3349HOJtBo&client_secret=B4E22853F677415BBC534DFB44DE4232&redirect_uri=http://10.70.16.197:8080/risk/system/riskLogin&scope=read";
    private final static String AUTH_URL = ReadProperties.getValueString("AUTH_URL");
    private final static String CLIENT_ID = ReadProperties.getValueString("CLIENT_ID");
    private final static String CLIENT_SECRET = ReadProperties.getValueString("CLIENT_SECRET");
    private final static String REDIECT_URI = ReadProperties.getValueString("REDIECT_URI");
    private final static String OAUTH_URL = ReadProperties.getValueString("OAUTH_URL");
    private final static String LOGIN2_URL = ReadProperties.getValueString("LOGIN2_URL");
    private final static String USER_URL = ReadProperties.getValueString("USER_URL");


    //private final static String LOGIN_URL = "http://10.66.9.69:8080/cas/buapxPasswordValidate";

    //private final static String VUE_URL = "http://10.70.16.197:9080/#/login?usercode=";


    private static String authentication(String username, String password) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("username", username);
        param.put("password", EncryptUtil.MD5Encode(password));
        param.put("syscode", "jv");
        //return HttpUtils.sendPost(LOGIN_URL, param);
        return HttpUtils.sendGet(LOGIN_URL+ "?username=" + username + "&password=" + param.get("password") + "&syscode=jv");
    }

    public static void main(String[] ager) {
       // String relust = authentication("178158", "1234qwer");

        System.out.println(EncryptUtil.MD5Encode("1234qwer"));
    }

    /**
     * 系统登陆入口
     *
     * @param map 用户code
     * @return AjaxResult
     */
    @PostMapping("loginCompany")
    @Log(title = "用戶登陆系统", integralType = IntegralType.Type1)
    public AjaxResult LoginCompany(@RequestBody Map<String, String> map) {
        String compId = map.get("compId");
        String compName = map.get("compName");
        XtzyCompany company = companyService.get(compId);
        XtzyUser user = getUser();
        user.setOrgCode("");
        user.setOrgName("");
        //当前登录人所属部门
        user.setExt1(compId);
        user.setExt2(company.getCompName());
        user.setExt3(company.getCompType());

        //当前登录人所属公司
        XtzyCompany topCompany = companyService.getTopCompany(compId, Short.parseShort("2"));
        if (topCompany != null) {
            user.setOrgCode(topCompany.getCompCode());
            user.setOrgName(topCompany.getCompName());

            XtzyCompany mCompany = companyService.getManageCompany(topCompany.getCompCode());
            if(mCompany != null){
                user.setManageCompCode(mCompany.getCompCode());
                user.setManageCompName(mCompany.getCompName());
            }

        }

        //获取当前登陆人所在公司下的所有角色
        List<SysRole> roleList = roleUserService.getUserRoles(user.getExt1(), user.getId());
        List<String> ids = roleList.stream().map(SysRole::getRoleKey).collect(Collectors.toList());
        user.setExt5(ids.toString());
        ShiroUtils.setUser(user);
        return success(user);
    }

    @RequestMapping("logout")
    public String ajaxLogout() {
        //清除shiro 权限缓存
        ShiroUtils.clearCachedAuthorizationInfo();
        ShiroUtils.logout();
        return "redirect:../login.jsp";
    }

    @RequestMapping("casLogout")
    public String casLogout(HttpSession session,HttpServletRequest request) {
        String logoutUrl ="login.jsp";
        try{
            if(null!=Class.forName("com.baosight.eplat.be.aa.client.config.OauthClientConfig")){
                logoutUrl = PlatApplicationContext.getProperty("eplat.security.client.logoutUrl");
            /*sdk1.2.0版本且使用业务交付配置时放开以下注释
            if(!StringUtils.isNotEmpty(logoutUrl)){
                String clientAddrProperty = PlatApplicationContext.getProperty("eplat.security.client.app.url");
                String serverAddrProperty = PlatApplicationContext.getProperty("eplat.security.client.auth.url");
                logoutUrl=serverAddrProperty + "/logout?callback=" + clientAddrProperty + "/logout";
            }*/
                logoutUrl = logoutUrl + "&token=" + session.getAttribute("oauth2_token");
            }
        }catch(ClassNotFoundException ex) {
            final Logger logger = LoggerFactory.getLogger("index");
            logger.info("未对接认证，使用默认登出链接");
        }
        request.setAttribute("logoutUrl",logoutUrl);
        return "redirect:" + logoutUrl;
    }

    /**
     * 统一认证登陆方法
     *
     * @param username 工号
     * @param password 密码
     * @return
     */
    @RequestMapping(value = "buapxLogin", method = RequestMethod.POST)
    public AjaxResult buapxLogin(String username, String password) {
        String result = authentication(username, password);
        if (result.contains("true")) {
            return success("登陆成功");
        } else if (result.contains("false")) {
            return error("登陆失败，用户名密码错误");
        } else if (result.contains("notActived")) {
            return error("登陆失败，用户名密码错误notActived");
        } else {
            return error("登陆失败，用户名密码错误");
        }
    }

    @RequestMapping(value = "getUser", method = RequestMethod.GET)
    public AjaxResult getUserToken(HttpServletRequest request) {
        XtzyUser user = getUser();
        return success(user);
    }

    /**
     * 单点登陆Api
     *
     * @param userid 工号
     * @return
     */
    @RequestMapping(value = "CasSso", method = RequestMethod.GET)
    public void CasSso(String userid, HttpServletResponse response) throws IOException {
        //解析获取登陆用户
        log.info("单点登陆进入userid：" + userid);
        String usercode = EncryptUtil.decrypt(userid);
        log.info("单点登陆进入工号：" + usercode);
        //认证用户是否在系统中
        XtzyUser user = userService.selectByName(usercode);
        if (user == null) {
            log.error("用户不存在或被禁用");
            response.sendRedirect(VUE_URL);
        } else {
            UsernamePasswordToken token = new UsernamePasswordToken(usercode, usercode);
            SecurityUtils.getSubject().login(token);
            response.sendRedirect(VUE_URL + usercode);
        }

    }

    @RequestMapping(value = "SsoLogin", method = RequestMethod.GET)
    public void ssoLogin(String userid, HttpServletResponse response,HttpServletRequest request) throws IOException {
        //解析获取登陆用户
        log.info("单点登陆进入userid：" + userid);
        log.info("单点登陆进入工号：" + userid);
        //认证用户是否在系统中
        XtzyUser user = userService.selectByName(userid);
        if (user == null) {
            log.error("用户不存在或被禁用");
            response.sendRedirect(VUE_URL);
        } else {
            UsernamePasswordToken token = new UsernamePasswordToken(userid, userid);
            token.setRememberMe(true);
            SecurityUtils.getSubject().login(token);

          /*  ShiroUtils.setUser(user);
            Session session = SecurityUtils.getSubject().getSession();
            session.setAttribute("token",userid);*/

            response.sendRedirect(VUE_URL + userid);

        }

    }


    //判断请求方式
    public boolean containsParameter(HttpServletRequest request, String paramName) {
        return request.getParameter(paramName) != null;
    }

    @RequestMapping("/caslogin")
    public void caslogin(HttpServletRequest httpServletRequest, HttpServletResponse resp) throws IOException {
        log.info("--------------------------进入caslogin-------------------------------");
        resp.sendRedirect(AUTH_URL);
    }

    //扫码登录
    @RequestMapping("/riskLogin")
    public void riskLogin(HttpServletRequest request, HttpServletResponse resp) {
        boolean hasParameter = containsParameter(request, "code");
        if (hasParameter) {
            try {
                log.info("---------------------获取token------------------------------------------");
                String code = request.getParameter("code");
                Map<String, String> map = new HashMap<>();
                map.put("client_id", CLIENT_ID);
                map.put("client_secret", CLIENT_SECRET);
                map.put("code", code);
                map.put("grant_type", "authorization_code");
                map.put("redirect_uri", REDIECT_URI);
                map.put("scope", "read");
                String s = HttpClientUtil.doPost(OAUTH_URL, map);

                JSONObject jsonObject = JSONObject.parseObject(s);
                String access_token = jsonObject.get("access_token").toString();

                log.info("---------------token获取结束----------------");
                tokenlogin(access_token,resp,request);
            } catch (Exception e ){
                e.printStackTrace();
            }
        }
    }


    //根据token登录
    public void tokenlogin(String token, HttpServletResponse resp,HttpServletRequest request) throws Exception {
        log.info("------------------根据token登录---------------------");
        URL url = new URL(USER_URL);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
        con.setRequestProperty("Authorization","Bearer" + " " + token);
        con.setDoOutput(true);
        con.setDoInput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.flush();
        wr.close();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        JSONObject jsonObject = JSONObject.parseObject(response.toString());
        String userId = jsonObject.get("userId").toString();
        con.disconnect();
        log.info("--------------------统一认证登陆成功获取用户信息--------------------");
        ssoLogin(userId,resp,request);
    }

    @RequestMapping(value = "tomcat", method = RequestMethod.GET)
    public AjaxResult getTomcat(HttpServletRequest request) {
        AjaxResult result = new AjaxResult();
        result.put("redis 服务地址：", ReadProperties.getValueString("iplat.redis.host"));
        result.put("redis 端口号：", ReadProperties.getValueString("iplat.redis.port"));
        result.put("redis 密码：", ReadProperties.getValueString("iplat.redis.pass"));
        result.put("socket服务地址：", ReadProperties.getValueString("nettySocketPath"));
        result.put("socket端口号：", ReadProperties.getValueString("nettySocketport"));
        result.put("文件上传地址：", ReadProperties.getValueString("projectServerFilePath"));
        result.put("数据库地址：", ReadProperties.getValueString("jdbc.url"));
        result.put("数据库用户：", ReadProperties.getValueString("jdbc.username"));
        result.put("数据库密码：", ReadProperties.getValueString("jdbc.password"));
        result.put("项目地址：", request.getServerPort());
        return result;
    }
}
